﻿

using Lrd.Permissions.Core.Entity;
using Lrd.Permissions.Repository;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Lrd.Permissions
{

    public class Repository<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
        where TPrimaryKey : IEquatable<TPrimaryKey>
    {
        //private readonly LrdPermissionsDbContext _dbContext;
        private readonly DbSet<TEntity> _dbSet;
        //private IUnitOfWork _unitOfWork;
        private readonly DbContext _dbContext=null;



        public Repository(IServiceProvider serviceProvider)
        {

            _dbContext = (serviceProvider.GetService(typeof(IUnitOfWork)) as IUnitOfWork).GetDbContext<TEntity, TPrimaryKey>();
            _dbSet = _dbContext.Set<TEntity>();

        }

        public IQueryable<TEntity> Entities => _dbSet.AsNoTracking();

        public IQueryable<TEntity> TrackEntities => _dbSet;

        public async Task BatchRemoveAsync(Expression<Func<TEntity, bool>> predicate)
        {
            var entitys = TrackEntities.Where(predicate).AsEnumerable();
            await _dbSet.AddRangeAsync(entitys);
            await _dbContext.SaveChangesAsync();

        }

        public async Task<int> DeleteAsync(TEntity entitie)
        {
            _dbSet.Remove(entitie);
            return await _dbContext.SaveChangesAsync();
        }

        public TEntity Get(TPrimaryKey id)
        {
            return _dbSet.Find(id);
        }

        public TEntity Get(Expression<Func<TEntity, bool>> predicate)
        {

            return _dbSet.FirstOrDefault(predicate);
        }

        public async Task<TEntity> GetAsync(TPrimaryKey id)
        {
            return await _dbSet.FindAsync(id);
        }

        public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _dbSet.FirstOrDefaultAsync(predicate);
        }

        public async Task<int> InsertAsync(TEntity entitie)
        {

            await _dbSet.AddAsync(entitie);
            return await _dbContext.SaveChangesAsync();
        }

        public async Task<int> InsertAsync(params TEntity[] entities)
        {
            await _dbSet.AddRangeAsync(entities);
            return await _dbContext.SaveChangesAsync();
        }

        public async Task<int> UpdateAsync(TEntity entitie)
        {
            _dbSet.Update(entitie);
            return await _dbContext.SaveChangesAsync();
        }
    }
}
